package com.heima.wemedia.service.impl;
import com.alibaba.fastjson.JSON;
import com.heima.common.constants.HotArticleConstants;
import com.heima.common.constants.WemediaConstants;
import com.heima.common.redis.CacheService;
import com.heima.feign.article.IArticleClient;
import com.heima.model.article.dtos.ArticleCommentDto;
import com.heima.model.comment.dtos.CommentConfigDto;
import com.heima.model.comment.dtos.RepayCommentDto;
import com.heima.model.comment.pojos.ApComment;
import com.heima.model.comment.pojos.ApCommentLike;
import com.heima.model.comment.pojos.ApCommentRepay;
import com.heima.model.comment.pojos.ApCommentRepayLike;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.mess.UpdateArticleMess;
import com.heima.model.user.pojos.ApUser;
import com.heima.model.wemedia.pojos.WmSensitive;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.common.SensitiveWordUtil;
import com.heima.utils.thread.ApUserThreadLocalUtil;
import com.heima.utils.thread.WeMediaThreadLocalUtil;
import com.heima.wemedia.mapper.WmSensitiveMapper;
import com.heima.wemedia.mapper.WmUserMapper;
import com.heima.wemedia.service.CommentManageService;
import com.heima.wemedia.service.GreenScanService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Transactional
public class CommentManageServiceImpl implements CommentManageService {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private WmUserMapper wmUserMapper;
    @Autowired
    private IArticleClient iArticleClient;
    @Autowired
    private CacheService cacheService;
    @Autowired
    private WmSensitiveMapper wmSensitiveMapper;
    @Autowired
    private GreenScanService greenScanService;
    @Autowired
    private KafkaTemplate<String,String> kafkaTemplate;


    /**
     * 打开或关闭评论
     * @param dto
     * @return
     */
    @Override
    public ResponseResult updateCommentStatus(CommentConfigDto dto) {
        // 查询文章评论
        List<ApComment> apComments = mongoTemplate.find(Query.query
                (Criteria.where("entryId").is(dto.getArticleId())), ApComment.class);
        // 查询评论回复
        for (ApComment apComment : apComments) {
            List<ApCommentRepay> commentRepayList = mongoTemplate.find(Query.query
                    (Criteria.where("commentId").is(apComment.getId())), ApCommentRepay.class);
            List<String> commentRepayIdList = commentRepayList.stream().map(ApCommentRepay::getId).distinct().collect(Collectors.toList());
            //先删除评论回复点赞
            mongoTemplate.remove(Query.query
                    (Criteria.where("commentRepayId").in(commentRepayIdList)), ApCommentRepayLike.class);
            //后删除评论回复
            mongoTemplate.remove(Query.query
                    (Criteria.where("entryId").is(dto.getArticleId())), ApCommentRepay.class);

            //先删除评论点赞
            mongoTemplate.remove(Query.query
                    (Criteria.where("commentId").is(dto.getArticleId())), ApCommentLike.class);
            //后删除评论
            mongoTemplate.remove(Query.query
                    (Criteria.where("entryId").is(dto.getArticleId())), ApComment.class);
        }
        //修改app端文章配置
        return iArticleClient.updateCommentStatus(dto);
    }

    /**
     * 查看评论列表
     * @param dto
     * @return
     */
    @Override
    public PageResponseResult findNewsComments(ArticleCommentDto dto) {
        Integer wmUserId = WeMediaThreadLocalUtil.get();
        dto.setWmUserId(wmUserId);
        return iArticleClient.findNewsComments(dto);
    }

    /**
     * @param dto
     * @Description: 回复评论
     * @Date 2023/6/28 11:08
     * @Author 朱传洋
     */
    @Override
    public ResponseResult replyComment(RepayCommentDto dto) {
        //1.非空校验
        if (dto==null|| StringUtils.isBlank(dto.getContent())){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        //判断用户是否登陆
        Integer wmUserId = WeMediaThreadLocalUtil.get();
        if (wmUserId==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //2.审核评论内容
        //2.1.自审核敏感词
        boolean isSensitive = handleSensitiveScan(dto.getContent());
        if(!isSensitive) return ResponseResult.errorResult(AppHttpCodeEnum.COMMENT_SCAN_FAIL);

        //2.2.百度审核评论
        boolean isTextScan = scanText(dto.getContent());
        if(!isTextScan) return ResponseResult.errorResult(AppHttpCodeEnum.COMMENT_SCAN_FAIL);

        //3.根据评论Id查询评论
        Query query = Query.query(Criteria.where("id").is(dto.getCommentId()));
        ApComment comment = mongoTemplate
                .findOne(query, ApComment.class);

        //4.判断评论是否存在
        if (comment==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.AP_USER_DATA_NOT_EXIST,"评论不存在或者已被删除");
        }
        //5.封装回复评论数据
        ApCommentRepay replyComment=new ApCommentRepay();
        replyComment.setCommentId(dto.getCommentId());
        replyComment.setAuthorId(wmUserId);
        //调用feign查询用户信息
        WmUser wmUser = wmUserMapper.selectById(wmUserId);
        replyComment.setAuthorName(wmUser.getName());
        replyComment.setContent(dto.getContent());
        replyComment.setCreatedTime(new Date());
        replyComment.setUpdatedTime(new Date());
        //6.保存到mongoDB
        mongoTemplate.save(replyComment);
        //7.修改评论表中的评论回复数量
        Update reply = Update.update("reply", comment.getReply() + 1);
        mongoTemplate.updateFirst(query,reply,ApComment.class);

        //8.发送消息更新article
        UpdateArticleMess mess = new UpdateArticleMess();
        mess.setArticleId(comment.getEntryId());
        mess.setAdd(1);
        mess.setType(UpdateArticleMess.UpdateArticleType.COMMENT);
        kafkaTemplate.send(HotArticleConstants.HOT_ARTICLE_SCORE_TOPIC, JSON.toJSONString(mess));
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);

    }

    /**
     * @param commentId
     * @Description: 删除评论
     * @Date 2023/6/29 11:10
     * @Author 张先赋
     */
    @Override
    public ResponseResult delectOneComment(String commentId) {
        //1.检查参数
        if (commentId==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        Integer wmUserId = WeMediaThreadLocalUtil.get();
        if (wmUserId==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //2.删除
        //删除评论
        mongoTemplate.remove(Query.query(Criteria.where("id").is(commentId)),ApComment.class);
        //删除评论的赞
        mongoTemplate.remove(Query.query(Criteria.where("commentId").is(commentId)),ApCommentLike.class);
        //找到评论回复
        List<ApCommentRepay> apCommentRepays = mongoTemplate.find(Query.query(Criteria.where("commentId").is(commentId)), ApCommentRepay.class);
        for (ApCommentRepay apCommentRepay : apCommentRepays) {
            //遍历删除评论和赞
            mongoTemplate.remove(Query.query(Criteria.where("commentRepayId").is(apCommentRepay.getId())),ApCommentRepayLike.class);
            mongoTemplate.remove(Query.query(Criteria.where("commentId").is(commentId)),ApCommentRepay.class);
        }
        //结果返回
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * @param commentRepayId
     * @Description: 删除评论回复
     * @Date 2023/6/29 11:10
     * @Author 张先赋
     */
    @Override
    public ResponseResult delectOneCommentRepay(String commentRepayId) {
        //1.检查参数
        if (StringUtils.isBlank(commentRepayId)){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        Integer wmUserId = WeMediaThreadLocalUtil.get();
        if (wmUserId==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //2.删除
        //减少被回复评论的评论数
        Update update=new Update();
        update.inc("reply", -1);
        //找到当前的回复
        ApCommentRepay apCommentRepay = mongoTemplate.findOne(Query.query(Criteria.where("id").is(commentRepayId)), ApCommentRepay.class);
        if (apCommentRepay!=null){
            mongoTemplate.updateFirst(Query.query(Criteria.where("id").is(apCommentRepay.getCommentId())), update,ApComment.class);
        }
        //删除
        mongoTemplate.remove(Query.query(Criteria.where("id").is(commentRepayId)),ApCommentRepay.class);
        mongoTemplate.remove(Query.query(Criteria.where("commentRepayId").is(commentRepayId)),ApCommentRepayLike.class);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 自管理的敏感词审核
     * @param content
     * @return
     */
    @Autowired
    private RedisTemplate redisTemplate;

    public boolean handleSensitiveScan(String content) {
        boolean flag = true;
        /*//获取所有的敏感词  -- 先从redis中获取
        List<String> sensitiveList = JSON.parseArray(cacheService.get("Sensitive"),String.class);
        */

        //获取所有的敏感词  -- 先从redis中获取
        List<String> sensitiveList = (List<String>) redisTemplate.opsForValue().get("Sensitive");
        if (sensitiveList == null) {
            List<WmSensitive> wmSensitives = wmSensitiveMapper.selectList(null);
            sensitiveList = wmSensitives.stream().map(WmSensitive::getSensitives).collect(Collectors.toList());
            //存入redis中
            cacheService.set("Sensitive",StringUtils.join(sensitiveList,","));
        }

        //初始化敏感词库
        SensitiveWordUtil.initMap(sensitiveList);

        //查看评论中是否包含敏感词
        Map<String, Integer> map = SensitiveWordUtil.matchWords(content);
        if(map.size() >0 ) {
            flag = false;
        }
        return flag;
    }


    /**
     * 审核评论中的纯文本内容
     *
     * @param text
     */
    private boolean scanText(String text) {

        //假设评论能审核通过
        boolean flag = true;

        try {
            //调用百度云API进行内容审核
            Map map = greenScanService.scanText(text);
            //不通过  不能评论
            if ((int) map.get("conclusionType") == WemediaConstants.BAIDU_SCAN_NO_PASS) {
                flag = false;
            }
            //疑似 不能评论
            if ((int) map.get("conclusionType") == WemediaConstants.BAIDU_SCAN_YS) {
                flag = false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }
}
